package com.ww.cheappliers.receive.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.mail.Folder;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeUtility;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import com.ww.cheappliers.Message;
import com.ww.cheappliers.common.EmailUtil;
import com.ww.cheappliers.common.PropertyUtil;
import com.ww.cheappliers.common.StaticVar;
import com.ww.cheappliers.receive.AbstractMessageReaper;

/**
 * 从邮箱收消息
 * @author tengHy
 *
 */
public class EmailReaperImpl extends AbstractMessageReaper implements StaticVar {
	private final String host, user, pwd;
	/**
	 * 每次接受完消息等待的时间 默认3分钟
	 */
	public long sleepMills = 3 * 60 * 1000;
	
	public EmailReaperImpl(String host, String user, String pwd){
		super();
		this.host = host;
		this.user = user;
		this.pwd = pwd;
	}
	
	/**
	 * 构造
	 * @param host pop3主机
	 * @param user 用户
	 * @param pwd 密码
	 */
	public EmailReaperImpl() {
		super();
		this.host = PropertyUtil.getProp(confKeyHost);
		this.user = PropertyUtil.getProp(confKeyUser);
		this.pwd = PropertyUtil.getProp(confKeyPwd);
	}
	
	final static Logger log = Logger.getLogger(EmailReaperImpl.class);

	public Message[] extractMessage() {
		try{
			// 查看邮件
			return getMailMessage();
		}catch(Exception ex){
			log.error("收邮件错误！", ex);
			return new Message[0];
		}finally{
			try {
				Thread.sleep(sleepMills);
			} catch (InterruptedException e) {
				log.error(e);
			}
		}
	}

	/**
	 * 获得最新的带 消息的邮件
	 * @return
	 * @throws MessagingException 
	 * @throws IOException 
	 */
	private Message[] getMailMessage() throws MessagingException, IOException{
		// 获得自上次收邮件以来 的消息邮件
		List<javax.mail.Message> holeMails 
			= new ArrayList<javax.mail.Message>();
		// 最后一次接收邮件的时间
		String lrd = StringUtils.trimToEmpty(PropertyUtil.getProp(confLastReceive));
		long lastReceiveDate = lrd.length() > 0 ? Long.parseLong(lrd) : 0;
		try{
			Properties p = new Properties(System.getProperties());
			Session sess = Session.getDefaultInstance(p);
			final Store store = sess.getStore("pop3");
			try{
				store.connect(host, user, pwd);
				final Folder f = store.getDefaultFolder().getFolder("INBOX");
				Assert.notNull(f, "此邮箱没有默认文件夹"); 
				
				try{
					f.open(Folder.READ_WRITE);
					
					// 倒叙遍历邮件
					javax.mail.Message firstMail = null;
					// 如果邮件已经看过了 那么认为剩下的都是旧邮件了
					for(int i=f.getMessageCount(); i>=1 ; i--){
						javax.mail.Message email = f.getMessages(i, i)[0];

						if(EmailUtil.getPop3MailReceiveDate(email).getTime()<= lastReceiveDate)
							break;
						
						if(firstMail == null)
							firstMail = email;
						
						// 提取标题
						String subject = MimeUtility.decodeText(email.getSubject());
						subject = StringUtils.trimToEmpty(subject);
						
						// 如果标题属于消息邮件
						if(subject.startsWith(MSG_SUBJECT_HEAD)){
							// 是消息邮件 新邮件往后压
							holeMails.add(0, email);
							// 这句在pop3下无用
							// email.saveChanges();
						}
					}
					
					// 存储一下最新一封的时间
					if(firstMail != null)
						PropertyUtil.setProp(confLastReceive, EmailUtil.getPop3MailReceiveDate(firstMail).getTime() + "");
					
					// 邮件转换为消息
					List<Message> ret = new ArrayList<Message>();
					for(javax.mail.Message em : holeMails){
						try{
							// 提取消息文本
							Message retMsg = new Message();
							retMsg.msgs = EmailUtil.getEmailMessage(em).toArray(new String[0]);
							
							ret.add(retMsg);
						}catch(Exception e){
							log.error("错误解析邮件！", e);
						}
					}
					
					return ret.toArray(new Message[0]);
				}finally{
					f.close(true);
				}
			}finally{
				store.close();
			}
		}catch(Exception e){
			log.error("收取邮件错误！", e);
		}
		
		return new Message[0];
	}



	
	public static void main(String[] args) {
		EmailReaperImpl ee = new EmailReaperImpl();
		Object o = ee.extractMessage();
		System.err.println(o);
	}
}
